﻿using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using Asdo.Controls;
using Asdo.Helpers;

namespace Asdo.Sample
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            _dragDropHelper = new DragDropHelper(this);

            var r = new Random(1);

            tabs.Items.Clear();
            for (int i = 1; i < 14; i++)
            {
                var t = (r.Next(0, 10000)/i).ToString();
                tabs.Items.Add(new TabItem {Header = t, Content = t});
            }

            list.Items.Clear();
            for (int i = 1; i < 1400; i++)
            {
                var t = (r.Next(0, 1000000) / i).ToString();
                list.Items.Add(t);
            }

        }

        public MainWindow(object data)
        {

            InitializeComponent();
            _dragDropHelper = new DragDropHelper(this);

                        tabs.Items.Clear();
            list.Visibility = Visibility.Collapsed;
            
            tabs.Items.Add(data);
        }


        private void Moving(object sender, MovingEventArgs e)
        {
            try
            {
                Debug.WriteLine("Moving  "+ e.OldIndex + " " + e.NewIndex);
                var tabCtrl = sender as TabControl;
                if (tabCtrl != null)
                {
                    var t = tabCtrl.Items[e.OldIndex];
                    tabCtrl.Items.RemoveAt(e.OldIndex);

                    tabCtrl.Items.Insert(e.NewIndex, t);
                    tabCtrl.SelectedIndex = e.NewIndex;
                }
            }
            catch(Exception exc)
            {
                Debug.WriteLine(exc.Message);
                Debug.WriteLine(exc.StackTrace);
            }
        }

        private readonly DragDropHelper _dragDropHelper;

        private void Draging(object sender, MovingEventArgs e)
        {
            e.Handled = true;
            var tabCtrl = sender as TabControl;
            if (tabCtrl != null)
            {
                var t = tabCtrl.Items[e.OldIndex] as TabItem;
                tabCtrl.Items.RemoveAt(e.OldIndex);

                if (tabCtrl.Items.Count == 0)
                {
                    Hide();
                }

                var dragResult = _dragDropHelper.DoDragDrop(tabCtrl.Name, t);

                if (tabCtrl.Items.Count > 0)
                {
                    switch (dragResult)
                    {
                        case DragResult.Escape:
                            tabCtrl.Items.Insert(e.OldIndex, t);
                            tabCtrl.SelectedIndex = e.OldIndex;
                            break;
                        case DragResult.Lost:
                            new MainWindow(t)
                                {
                                    Top = _dragDropHelper.Top,
                                    Left = _dragDropHelper.Left
                                }.Show();
                            break;
                    }
                }
                else
                {
                    switch (dragResult)
                    {
                        case DragResult.Lost:
                            Top = _dragDropHelper.Top;
                            Left = _dragDropHelper.Left;
                            goto case DragResult.Escape;
                        case DragResult.Escape:
                            tabCtrl.Items.Insert(e.OldIndex, t);
                            tabCtrl.SelectedIndex = e.OldIndex;
                            Show();
                            break;
                        case DragResult.None:
                            Close();
                            break;
                    }
                }
            }
        }

        private void TabsPreviewDragOver(object sender, DragEventArgs e)
        {
            e.Effects = DragDropEffects.None;
            e.Handled = true;

            var tabCtrl = (TabControl)sender;
            var tab = e.Data.GetData(tabCtrl.Name) as TabItem;

            if (e.Source is TabItem || IsSwipe(e.OriginalSource))
            {
                e.Effects = DragDropEffects.Move;
            }
        }

        private void TabsPreviewDrop(object sender, DragEventArgs e)
        {
            e.Effects = DragDropEffects.None;
            e.Handled = true;

            var tabCtrl = (TabControl)sender;
            var item = e.Data.GetData(tabCtrl.Name) as TabItem;

            var tab = e.Source as TabItem;
            var swipe = e.OriginalSource as SwipePanel;

            if (item != null && (tab != null || IsSwipe(e.OriginalSource)))
            {
                e.Effects = DragDropEffects.Move;
                e.Handled = true;

                var i = tab == null
                            ? SwipePanel.GetChildIndexUnderMouse(Orientation.Horizontal, e.GetPosition, tabs.Items)
                            : tabCtrl.Items.IndexOf(tab);

                Debug.WriteLine("Index drop = " + i);

                if ( i >= 0 )
                {
                    tabCtrl.Items.Insert(i, item);
                    Debug.WriteLine("insert " + i);
                }
                else
                {
                    i = tabCtrl.Items.Add(item);
                    Debug.WriteLine("add " + i);
                }

                tabCtrl.SelectedItem = item;
            }

            SwipePanel.SetIsSwipeLocked(tabCtrl, true);

            Debug.WriteLine("Drop " + e.Effects);
            
        }

        private void TabsPreviewDragEnter(object sender, DragEventArgs e)
        {
            e.Effects = DragDropEffects.None;
            e.Handled = true;

            var tabCtrl = (TabControl)sender;
            var tab = e.Data.GetData(tabCtrl.Name) as TabItem;

            if (tab != null)
            {
                if (e.Source is TabItem || IsSwipe(e.OriginalSource))
                {
                    e.Effects = DragDropEffects.Move;
                }
            }
        }

        private bool IsSwipe(object originalSource)
        {
            var a = originalSource as ScrollViewer;
            return a != null && a.Name == "svSwipe";
        }

        private void TabsMouseUp(object sender, MouseButtonEventArgs e)
        {
            SwipePanel.SetIsSwipeLocked((DependencyObject) sender,false);
        }

        private void MovingS(object sender, MovingEventArgs e)
        {
            try
            {
                Debug.WriteLine("Moving  " + e.OldIndex + " " + e.NewIndex);
                var listBox = sender as ListBox;
                if (listBox != null)
                {
                    var t = listBox.Items[e.OldIndex];
                    listBox.Items.RemoveAt(e.OldIndex);

                    listBox.Items.Insert(e.NewIndex, t);
                    listBox.SelectedItem = t;
                }
            }
            catch (Exception exc)
            {
                Debug.WriteLine(exc.Message);
                Debug.WriteLine(exc.StackTrace);
            }
        }

        private Point? _pos;

        private void list_MouseMove(object sender, MouseEventArgs e)
        {
            var sv = e.OriginalSource as ScrollViewer;

            if (sv != null && _pos.HasValue && e.LeftButton == MouseButtonState.Pressed)
            {
                var p = e.GetPosition(list);
                var dy = p.Y - _pos.Value.Y;
                var oy = sv.VerticalOffset;
                //if (Math.Abs(dy) < 50)
                {
                    ScrollBar.ScrollToVerticalOffsetCommand.Execute(oy - dy,sv);
                    //sv.ScrollToVerticalOffset(oy - dy);
                    sv.InvalidateScrollInfo();
                    e.Handled = true;
                }
                Debug.WriteLine(oy+ " + (" + dy + ") = ");
                _pos = p;
            }
        }

        private void list_MouseEnter(object sender, MouseEventArgs e)
        {
            _pos = e.GetPosition(list);
        }

        private void list_MouseLeave(object sender, MouseEventArgs e)
        {
            _pos = null;
        }
    }
}
